﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DrawPanel
{
    public partial class PicBoxSelectControl : UserControl
    {
        public PicBoxSelectControl()
        {
            //this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
            InitializeComponent();
        }

        // 定义框选事件
        public event EventHandler<Rectangle> BoxSelect;
        // 定义鼠标点击事件
        public event EventHandler<Point> MouseLeftClick;
        public event EventHandler<Point> MouseRightClick;

        Point start;
        Point end;
        bool onDraw = false;
        private Bitmap _pic;
        private Bitmap tmp;
        Rectangle preRect = Rectangle.Empty;

        public Bitmap Pic
        {
            get { return _pic; }
            set {
                if (value == null)
                    return;
                _pic = value;
                panel1.Size = _pic.Size;
                panel1.BackgroundImage = _pic;
                tmp = new Bitmap(Pic.Width, Pic.Height);
                // 透明填充
                Graphics g = Graphics.FromImage(tmp);
                g.FillRectangle(new SolidBrush(Color.FromArgb(0, 0, 0, 0)), new Rectangle(0, 0, Pic.Width, Pic.Height));
                g.Dispose();
            }
        }

        private void PaintControl_MouseDown(object sender, MouseEventArgs e)
        {
            onDraw = false;
            if (e.Button != MouseButtons.Left)
                return;
            start = e.Location;
        }

        private void PaintControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
            end = e.Location;
            // 引发窗口重绘事件
            var rect = GetRectangle();
            if(rect.Width > 2 && rect.Height > 2){
                onDraw = true;
                panel1.Invalidate();
            }
        }

        private void PaintControl_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
            end = e.Location;
            onDraw = false;
            panel1.Invalidate();

            var rect = GetRectangle();
            if (rect.Width > 4 && rect.Height > 4)
            {
                if(BoxSelect != null)
                {
                    BoxSelect(this, rect);
                }
            }
        }

        Rectangle GetRectangle()
        {
            return new Rectangle(start.X < end.X ? start.X : end.X,
                start.Y < end.Y ? start.Y : end.Y,
                Math.Abs(end.X - start.X) + 1,
                Math.Abs(end.Y - start.Y) + 1);
        }

        private void PaintControl_Paint(object sender, PaintEventArgs e)
        {
            if (_pic == null)
                return;
            // 绘制矩形
            if (onDraw || !preRect.IsEmpty)
            {
                Graphics bg = Graphics.FromImage(tmp);
                var rect = GetRectangle();

                bg.CompositingMode = CompositingMode.SourceCopy;
                if (!preRect.IsEmpty)
                {
                    bg.FillRectangle(new SolidBrush(Color.FromArgb(0, 0, 0, 0)), preRect);
                    preRect = Rectangle.Empty;
                }
                if (onDraw)
                {
                    bg.DrawRectangle(Pens.Red, rect);
                    preRect = rect;
                    preRect.Width++;
                    preRect.Height++;
                }
                bg.CompositingMode = CompositingMode.SourceOver;

                bg.Dispose();

                e.Graphics.DrawImage(tmp, 0, 0);
            }
        }

        private void PaintControl_MouseClick(object sender, MouseEventArgs e)
        {
            Debug.WriteLine("MouseClick");
            if (e.Button == MouseButtons.Left)
            {
                if(MouseLeftClick != null)
                {
                    MouseLeftClick(this, e.Location);
                }
            }else if(e.Button == MouseButtons.Right)
            {
                if(MouseRightClick != null)
                {
                    MouseRightClick(this, e.Location);
                }
            }
        }
    }
}
